import type { RouteRecordRaw } from "vue-router"
import { pinia } from "@/pinia"
import { constantRoutes, dynamicRoutes, ResourceRoutePath } from "@/router"
import { routerConfig } from "@/router/config"
import { flatMultiLevelRoutes } from "@/router/helper"
import { getProjectModules, removeProjectInfo } from "@/common/utils/cache/local-storage"
import { isPathExist } from "@/common/utils/permission"
import { useTagsViewStore } from "./tags-view"
import { cloneDeep, isEmpty } from "lodash"

function hasPermission(roles: string[], route: RouteRecordRaw) {
  const routeRoles = route.meta?.roles
  return routeRoles ? roles.some(role => routeRoles.includes(role)) : true
}

function filterDynamicRoutes(routes: RouteRecordRaw[], roles: string[]) {
  const res: RouteRecordRaw[] = []
  routes.forEach((route) => {
    const tempRoute = { ...route }
    if (hasPermission(roles, tempRoute)) {
      if (tempRoute.children) {
        tempRoute.children = filterDynamicRoutes(tempRoute.children, roles)
      }
      res.push(tempRoute)
    }
  })
  return res
}

function filterInnerRoutes(routes: RouteRecordRaw[], innerName?: string): RouteRecordRaw[] {
  const res: RouteRecordRaw[] = []

  routes.forEach((route) => {
    const tempRoute = { ...route }
    let hasChildren = false // 用于标记是否有匹配的子路由

    // 处理当前路由
    const isCurrentRouteValid = (innerName === undefined && route.name !== "MyProject") || route.name === innerName
    if (isCurrentRouteValid) {
      res.push(tempRoute)
    } else {
      // 处理子路由
      if (route.children && route.children.length > 0) {
        const filteredChildren = filterInnerRoutes(route.children, innerName)
        if (filteredChildren.length > 0) {
          hasChildren = true // 标记有匹配的子路由
          tempRoute.children = filteredChildren // 将匹配的子路由添加到当前路由
        }
      }

      // 只有在有匹配的子路由时，才将当前路由添加到结果中
      if (hasChildren) {
        res.push(tempRoute)
      }
    }
  })

  return res
}

export const usePermissionStore = defineStore("permission", () => {
  // 可访问的路由
  const routes = ref<RouteRecordRaw[]>([])
  // 有访问权限的动态路由
  const addRoutes = ref<RouteRecordRaw[]>([])
  // 是否为子菜单
  const childFlag = ref<string>()
  // 显示的路由
  const showMenus = ref<RouteRecordRaw[]>([])

  const tagsViewStore = useTagsViewStore()

  // 根据角色生成可访问的 Routes（可访问的路由 = 常驻路由 + 有访问权限的动态路由）
  const setRoutes = (roles: string[]) => {
    // const innerName = childFlag.value
    let accessedRoutes: RouteRecordRaw[] = []
    // const innerRoutes = filterInnerRoutes(dynamicRoutes, innerName == null ? undefined : innerName)
    accessedRoutes = filterDynamicRoutes(dynamicRoutes, roles)
    set(accessedRoutes)
  }

  // 所有路由 = 所有常驻路由 + 所有动态路由
  const setAllRoutes = () => {
    // const innerName = getChildFlag()
    // const innerRoutes = filterInnerRoutes(dynamicRoutes, innerName == null ? undefined : innerName)
    set(dynamicRoutes)
  }

  // 统一设置
  const set = (accessedRoutes: RouteRecordRaw[]) => {
    routes.value = constantRoutes.concat(accessedRoutes)
    addRoutes.value = routerConfig.thirdLevelRouteCache ? flatMultiLevelRoutes(accessedRoutes) : accessedRoutes
    setShowMenus()
  }

  const setChildFlag = (type: string) => {
    childFlag.value = type
    setShowMenus()
  }

  const removeChildFlag = () => {
    childFlag.value = undefined
    tagsViewStore.delAllViews()
    setShowMenus()
  }

  const setShowMenus = () => {
    showMenus.value = getNoHiddenRoutes()
  }

  function getNoHiddenRoutes() {
    const tempRoutes = cloneDeep(routes.value)
    if (!childFlag.value) {
      return tempRoutes.filter(item => !item.meta?.hidden)
    }
    return processRoutes(tempRoutes, childFlag.value)
  }

  function resetChildFlag(fullPath: string) {
    // 如果 fullPath 是根路径，则清除子标志
    if (fullPath === "/") {
      removeChildFlag()
      // removeProjectInfo()
      return
    }
    let rootMenu
    // 移除 query 参数
    const pathWithoutQuery = fullPath.split("?")[0]
    Object.keys(ResourceRoutePath).forEach((name) => {
      if (isPathExist(ResourceRoutePath[name], pathWithoutQuery)) {
        rootMenu = name
        return
      }
    })
    if (rootMenu === undefined) {
      removeChildFlag()
      // removeProjectInfo()
    } else {
      setChildFlag(rootMenu)
    }
  }

  return { childFlag, routes, addRoutes, showMenus, setRoutes, setAllRoutes, setChildFlag, removeChildFlag, resetChildFlag, setShowMenus }
})

/** 显示的子菜单 */
const showingChildren = (childRoutes: RouteRecordRaw[]) => {
  return childRoutes.filter(child => !child.meta?.hidden) ?? []
}

const isModules = ((moduleName: string, childFlag: string | undefined) => {
  if (moduleName == undefined) {
    return true
  }
  const modules = getProjectModules()
  if (childFlag == "MyProject") {
    return modules.indexOf(moduleName) != -1
  } else {
    return true
  }
})

const setRouteAffix = (childRoutes: RouteRecordRaw[]) => {
  const curRoute = childRoutes[0]
  if (curRoute.children && showingChildren(curRoute.children).length == 1 && curRoute.children[0].meta) {
    curRoute.children[0].meta.affix = true
  } else if (curRoute.children) {
    setRouteAffix(curRoute.children)
  } else {
    curRoute.meta && (curRoute.meta.affix = true)
  }
}

// 处理innerlink路由，如果父配置了innerlink，左侧菜单显示子目录
function processRoutes(routes: RouteRecordRaw[], childFlag: string | undefined): RouteRecordRaw[] {
  const menus: RouteRecordRaw[] = []
  // 递归遍历路由
  function traverse(routeItems: RouteRecordRaw[]) {
    routeItems.forEach((item) => {
      // 如果当前路由名称与 childFlag 相同且是内部链接
      if (item.name === childFlag && item.meta?.isInnerLink) {
        if (item.children) {
          // 过滤符合模块条件的子路由
          const children = item.children.filter(child =>
            child.meta && isModules(child.meta.moduleName as string, childFlag)
          )
          // 设置路由前缀
          if (children.length > 0) {
            setRouteAffix(children)
          }
          // 添加到菜单数组
          menus.push(...children.filter(item => !item.meta?.hidden))
        }
      }
      // 递归处理子路由
      if (item.children && item.children.length > 0) {
        traverse(item.children)
      }
    })
  }
  // 开始递归遍历
  traverse(routes)

  if (isEmpty(childFlag)) {
    // 过滤掉隐藏的菜单项
    return menus.filter(item => !item.meta?.hidden)
  } else {
    return menus
  }
}

/**
 * @description 在 SPA 应用中可用于在 pinia 实例被激活前使用 store
 * @description 在 SSR 应用中可用于在 setup 外使用 store
 */
export function usePermissionStoreOutside() {
  return usePermissionStore(pinia)
}
